datetime的介绍
datetime 和 time 的区别:
- datetime 是在 time 模块的基础上封装的
- datetime 所返回的是时间对象
注意:在本章节中虽然打印出来是一个日期字符串,但是实际上是一个日期对象,除非使用了格式化日期对象
取当前时间
1. 取当前时间
import datetime
datetime.datetime.now() # 2019-05-02 12:30:47.928455 -> 类型: <class 'datetime.datetime'>
datetime.datetime.today() # 2019-05-02 12:30:47.928455 -> 类型: <class 'datetime.datetime'>
datetime.date.today() # 2019-05-02 -> 类型: <class 'datetime.date'>
指定时间的日期对象
1. 指定时间的日期对象
import datetime
datetime.datetime(year=2019, month=3, day=20, hour=10, minute=1, second=32, microsecond=1) # 2019-03-20 10:01:32.000001 -> 类型: <class 'datetime.datetime'>
datetime.date(year=2019, month=3, day=20) # 2019-03-20 -> 类型: <class 'datetime.date'>
datetime.time(hour=10, minute=1, second=32, microsecond=1) # 10:01:32.000001 -> 类型: <class 'datetime.time'>
获取日期对象中的具体时间参数
1. 获取日期对象中的日期和时间(返回值: 日期对象)
- 日期对象.date() -> 获取日期对象中的日期
# 获取日期
date = datetime.datetime.now().date() # 2019-06-11 -> 类型:<class 'datetime.date'>
date = datetime.datetime(year=2019, month=3, day=20, hour=10, minute=1, second=32, microsecond=1).date() # 2019-03-20 -> 类型:<class 'datetime.date'>
- 日期对象.time() -> 获取日期对象中的时间
# 获取时间
date = datetime.datetime.now().time() # 16:05:49.278866 -> 类型:<class 'datetime.time'>
date = datetime.datetime(year=2019, month=3, day=20, hour=10, minute=1, second=32, microsecond=1).time() # 10:01:32.000001 -> 类型:类型:<class 'datetime.time'>
2. 获取日期对象中的年月日时分秒(返回值:字符串)
import datetime
# date_obj = datetime.datetime(year=2019, month=3, day=20, hour=10, minute=1, second=32, microsecond=1)
date_obj = datetime.datetime.now()
print(date_obj.year) # 2019
print(date_obj.month) # 5
print(date_obj.day) # 2
print(date_obj.hour) # 12
print(date_obj.minute) # 58
print(date_obj.second) # 43
print(date_obj.microsecond) # 202714
timedelta 日期对象
1. timedelta 日期对象的介绍
- timedelta 日期对象: 通过 日期对象之间的运算 或 .timedelta() 方法 所返回的一个对象
2. .timedelta() 方法
- .timedelta() -> 返回一个指定天数的 timedelta 日期对象,用于日期的运算
- .timedelta(weeks=float, days=float, hours=float, minutes=float, seconds=float, microseconds=float, milliseconds=float) 参数
- weeks -> 指定周数
- days -> 指定天数
- hours -> 指定小时
- minutes -> 指定分钟
- seconds -> 指定秒数
- microseconds -> 指定微秒
- milliseconds -> 指定毫秒
import datetime
date_obj = datetime.datetime.now() # 2019-05-02 13:32:02.220621 -> 类型: <class 'datetime.datetime'>
days = datetime.timedelta(days=7) # 7 days, 0:00:00 -> 指定一个7天的对象 -> 类型: <class 'datetime.timedelta'>
new_date_obj = date_obj + days # 2019-05-09 13:22:49.300992 -> 获取当前时间的7天后日期 -> 类型: <class 'datetime.datetime'>
import datetime
date_obj = datetime.datetime(year=2019, month=3, day=20, hour=10, minute=1, second=32, microsecond=1) # 2019-03-20 10:01:32.000001 -> 类型: <class 'datetime.datetime'>
days = datetime.timedelta(days=7) # 7 days, 0:00:00 -> 指定一个7天的对象 -> 类型: <class 'datetime.timedelta'>
new_date_obj = date_obj + days # 2019-03-27 10:01:32.000001 -> 获取指定时间的7天后日期 -> 类型: <class 'datetime.datetime'>
3. timedelta 日期对象所提供的属性(常用的)
- .days
- .timedelta()返回的 timedelta 日期对象代表: 获取指定天数
- 两个日期对象之间运算后返回的 timedelta 日期对象代表: 获取两个日期之间的天数差
- .seconds
- .timedelta()返回的 timedelta 日期对象代表: 获取指定秒数
- 两个日期对象之间运算后返回的 timedelta 日期对象代表: 获取两个日期之间的秒数差,忽略微秒数,忽略天数
- .microseconds
- .timedelta()返回的 timedelta 日期对象代表: 获取指定微妙
- 两个日期对象之间运算后返回的 timedelta 日期对象代表: 获取两个日期之间的微妙差
- .timedelta()返回的 timedelta 日期对象
import datetime
timedelta_obj = datetime.timedelta(weeks=1)
d = timedelta_obj.days # 7
s = timedelta_obj.seconds # 0
ms = timedelta_obj.microseconds # 0
- 两个日期对象之间运算后返回的 timedelta 日期对象
import datetime
now = datetime.datetime.now()
previous_time = datetime.datetime(year=2019, month=3, day=20, hour=10, minute=1, second=32, microsecond=1)
time_difference = now - previous_time
d = time_difference.days # 132
s = time_difference.seconds # 45146
ms = time_difference.microseconds # 591401
4. timedelta 日期对象所提供的方法(常用的)
- .total_seconds() -> 获取两个时间之间的总差(以秒为单位)
import datetime
now = datetime.datetime.now()
previous_time = datetime.datetime(year=2019, month=3, day=20, hour=10, minute=1, second=32, microsecond=1)
time_difference = now - previous_time
ts = time_difference.total_seconds() # 11451066.794178
计算时间差
注意: 日期对象之间的运算必须是同一个时间类型(例: datetime 必须和 datetime 进行运算,时区类型必须一致,且 datetime 不能和 date 进行运算,但是 datetime/date 可以与 timedelta 日期对象 进行运算)
1. 日期对象之间进行运算
- 注意: 日期对象在进行运算后会返回一个 timedelta 日期对象 和 .timedelta() 返回的 timedelta 日期对象是一样的
import datetime
date_obj1 = datetime.datetime.now() # 2019-05-02 13:41:15.291482 -> 类型: <class 'datetime.datetime'>
date_obj2 = datetime.datetime(year=2019, month=3, day=20, hour=10, minute=1, second=32, microsecond=1) # 2019-03-20 10:01:32.000001 -> 类型: <class 'datetime.datetime'>
date_t = date_obj1 - date_obj2
print(date_t) # 43 days, 3:39:43.291481 -> 类型: <class 'datetime.timedelta'>
print(date_t.days) # 43
print(date_t.seconds) # 13183
print(date_t.microseconds) # 291481
- 注意: 日期对象在进行运算后会返回一个 timedelta 日期对象 和 .timedelta() 返回的 timedelta 日期对象是一样的,所以可以和下面的.timedelta()一样对日期的运算,然后返回一个日期对象
import datetime
date_obj1 = datetime.datetime.now() # 2019-05-02 13:39:36.784401 -> 类型: <class 'datetime.datetime'>
date_obj2 = datetime.datetime(year=2019, month=3, day=20, hour=10, minute=1, second=32, microsecond=1) # 2019-03-20 10:01:32.000001 -> 类型: <class 'datetime.datetime'>
date_t = date_obj1 - date_obj2 # 43 days, 3:38:04.784400 -> 类型: <class 'datetime.timedelta'>
new_date_obj = datetime.datetime.now() + date_t # 2019-06-14 17:17:41.568801 -> 类型: <class 'datetime.datetime'>
2. 日期对象 和 timedelta 日期对象 之间进行运算
- 说明: 在原本的日期对象上增加时间或者减少时间,并且返回一个新的日期对象(非 timedelta 日期对象)
- 日期对象和timedelta 日期对象 之间进行运算会返回一个新的日期对象(非 timedelta 日期对象)
import datetime
date_obj = datetime.datetime.now() # 2019-05-02 13:32:02.220621 -> 类型: <class 'datetime.datetime'>
days = datetime.timedelta(days=7) # 7 days, 0:00:00 -> 指定一个7天的对象 -> 类型: <class 'datetime.timedelta'>
new_date_obj = date_obj + days # 2019-05-09 13:22:49.300992 -> 获取当前时间的7天后日期 -> 类型: <class 'datetime.datetime'>
import datetime
date_obj = datetime.datetime(year=2019, month=3, day=20, hour=10, minute=1, second=32, microsecond=1) # 2019-03-20 10:01:32.000001 -> 类型: <class 'datetime.datetime'>
days = datetime.timedelta(days=7) # 7 days, 0:00:00 -> 指定一个7天的对象 -> 类型: <class 'datetime.timedelta'>
new_date_obj = date_obj + days # 2019-03-27 10:01:32.000001 -> 获取指定时间的7天后日期 -> 类型: <class 'datetime.datetime'>
3. 错误示范
- 注意: 日期对象之间的运算必须是同一个时间类型(例: datetime 必须和 datetime 进行运算,时区类型必须一致,且 datetime 不能和 date 进行运算,但是 datetime/date 可以与 timedelta 日期对象 进行运算)
- datetime 和 date 进行运算
import datetime
now = datetime.datetime.now()
previous_time = datetime.date(year=2019, month=3, day=20)
result = now - previous_time # datetime 类型 和 date类型 不能进行运算
- 时区类型不一致进行运算(即: 一个日期对象有时区,一个日期对象没有时区)
import datetime
import pytz
date_obj1 = datetime.datetime.now() # offset-naive: 不含时区
date_obj2 = datetime.datetime(year=2019, month=3, day=20, hour=10, minute=1, second=32, microsecond=1, tzinfo=pytz.timezone('UTC')) # offset-aware: 包含时区
date_t = date_obj1 - date_obj2 # 时区类型不一致不能进行运算
日期对象之间的比较
注意: 日期对象之间的比较必须是同一个时间类型(例: datetime 必须和 datetime 进行比较,timedelta 日期对象 必须和 timedelta 日期对象 比较,时区类型必须一致,且 datetime 不能和 date 进行比较)
1. 日期对象 和 日期对象的比较
import datetime
now = datetime.datetime.now()
previous_time = datetime.datetime(year=2019, month=3, day=20, hour=10, minute=1, second=32, microsecond=1)
result = now > previous_time # True
2. timedelta 日期对象 和 timedelta 日期对象的比较
import datetime
now = datetime.datetime.now()
previous_time = datetime.datetime(year=2019, month=3, day=20, hour=10, minute=1, second=32, microsecond=1)
time_difference = now - previous_time # 类型: <class 'datetime.timedelta'>, 日期对象之间进行运算后返回的类型和.timedelta()返回的类型是一样
tow_week = datetime.timedelta(weeks=2) # 类型: <class 'datetime.timedelta'>
result = time_difference > tow_week # True
import datetime
one_day = datetime.timedelta(days=3) # 类型: <class 'datetime.timedelta'>
tow_week = datetime.timedelta(weeks=2) # 类型: <class 'datetime.timedelta'>
result = one_day > tow_week # False
3. 错误示范
- 注意: 日期对象之间的比较必须是同一个时间类型(例: datetime 必须和 datetime 进行比较,timedelta 日期对象 必须和 timedelta 日期对象 比较,时区类型必须一致,且 datetime 不能和 date 进行比较)
- datetime 和 date 进行比较
import datetime
now = datetime.datetime.now()
previous_time = datetime.date(year=2019, month=3, day=20)
result = now > previous_time # datetime 类型 和 date类型 不能进行比较,因为日期类型不一致
- datetime 和 timedelta 进行比较
import datetime
now = datetime.datetime.now()
two_week = datetime.timedelta(weeks=2)
result = now > two_week # datetime 类型 和 timedelta类型 不能进行比较,因为日期类型不一致
- 时区类型不一致进行比较(即: 一个日期对象有时区,一个日期对象没有时区)
import datetime
import pytz
date_obj1 = datetime.datetime.now() # offset-naive: 不含时区
date_obj2 = datetime.datetime(year=2019, month=3, day=20, hour=10, minute=1, second=32, microsecond=1, tzinfo=pytz.timezone('UTC')) # offset-aware: 包含时区
date_t = date_obj1 > date_obj2 # 时区类型不一致不能进行比较
时区类型
1.时区类型
- offset-naive: 不含时区
- offset-aware: 包含时区
2.查看日期对象是否包含时区
- 日期对象.tzinfo
- 通过 datetime 模块生成的日期对象 或 从数据库中获取到的日期对象(前提: USE_TZ = False -> [setting.py]) 都不会包含时区
import datetime
from app01.models import *
# --------------- 通过 datetime 模块生成的日期对象 -------------------
now = datetime.datetime.now()
print(now.tzinfo) # None -> offset-naive: 不含时区
specified_date = datetime.datetime(year=2019, month=3, day=20, hour=10, minute=1, second=32, microsecond=1)
print(now.tzinfo) # None -> offset-naive: 不含时区
# --------------- 从数据库中获取到的日期对象(前提: USE_TZ = False -> [setting.py]) -------------------
time_obj = TimeTable.objects.filter(id=1).first()
print(time_obj.time.tzinfo) # None -> offset-naive: 不含时区
# settings.py
USE_TZ = False # 查询出不含时区的日期对象
- 从数据库中获取到的日期对象(前提: USE_TZ = True -> [setting.py]) 或 手动设置了时区的日期对象 都会包含时区
import datetime
import pytz
from app01.models import *
# --------------- 从数据库中获取到的日期对象(前提: USE_TZ = True -> [setting.py]) -------------------
time_obj = TimeTable.objects.filter(id=1).first()
print(time_obj.time.tzinfo) # UTC -> offset-aware: 包含时区
# --------------- 手动设置了时区的日期对象 -------------------
now = datetime.datetime.now().replace(tzinfo=pytz.timezone('UTC'))
print(now.tzinfo) # UTC -> offset-aware: 包含时区
specified_date = datetime.datetime(year=2019, month=3, day=20, hour=10, minute=1, second=32, microsecond=1, tzinfo=pytz.timezone('UTC'))
print(now.tzinfo) # UTC -> offset-aware: 包含时区
# settings.py
USE_TZ = True # 查询出包含时区的日期对象
3.修改日期对象的时区
- 添加时区
- 通过 pytz 模块创建某个时区对象
- 使用 tzinfo 属性添加时区对象
import datetime
import pytz
now = datetime.datetime.now().replace(tzinfo=pytz.timezone('UTC'))
print(now.tzinfo) # UTC -> offset-aware: 包含时区
specified_date = datetime.datetime(year=2019, month=3, day=20, hour=10, minute=1, second=32, microsecond=1, tzinfo=pytz.timezone('UTC'))
print(now.tzinfo) # UTC -> offset-aware: 包含时区
- 去除时区
import datetime
from app01.models import *
# ------------------------- 查询出来的日期对象 ----------------------------------
time_obj = TimeTable.objects.filter(id=1).first()
time_obj_time = time_obj.time.replace(tzinfo=None)
print(time_obj_time.tzinfo) # None -> offset-naive: 不含时区
# ----------------- 通过 datetime 模块生成的日期对象(一般是不用去除的,因为默认就不带时区,这里只是为了演示) -----------------
now = datetime.datetime.now().replace(tzinfo=None)
print(now.tzinfo) # None -> offset-naive: 不含时区
specified_date = datetime.datetime(year=2019, month=3, day=20, hour=10, minute=1, second=32, microsecond=1, tzinfo=None)
print(now.tzinfo) # None -> offset-naive: 不含时区
4.在日常开发中要注意获取到的时间是否相差 8 小时
5.在 Django 开发中 日期的运算 和 比较 都需要注意时区类型
- 不同时区的类型的运算和比较错误提醒(即: 一个日期对象有时区,一个日期对象没有时区)

Traceback (most recent call last):
File "C:/Users/Mr. Yeung/Desktop/PyFolder/test_time/app01/tests.py", line 27, in <module>
print(time_obj.time - now)
TypeError: can't subtract offset-naive and offset-aware datetimes
- 解决办法 -> 统一时间类型
- 统一为 offset-naive: 不含时区
- 方法一 -> 将查询到的日期对象变成不包含时区的日期对象
import datetime
from app01.models import *
time_obj = TimeTable.objects.filter(id=1).first()
time_obj_time = time_obj.time.replace(tzinfo=None) # 将查询到的日期对象变成不包含时区的日期对象
print(time_obj_time.tzinfo) # None -> offset-naive: 不含时区
now = datetime.datetime.now()
print(now.tzinfo) # None -> offset-naive: 不含时区
difference_time = now - time_obj_time # 10:46:45.613783
result = now > time_obj_time # True
- 方法二 -> 在 settings.py 中设置 USE_TZ = False,那么直接查询到的是不带时区的日期对象
# settings.py
USE_TZ = False
import datetime
from app01.models import *
time_obj = TimeTable.objects.filter(id=1).first()
print(time_obj.time.tzinfo) # None -> offset-naive: 不含时区
now = datetime.datetime.now()
print(now.tzinfo) # None -> offset-naive: 不含时区
difference_time = now - time_obj.time # 10:51:10.098679
result = now > time_obj.time # True
- 统一为 offset-aware: 包含时区
- 前提: settings.py 中的设置 USE_TZ = True
# settings.py
USE_TZ = True
import datetime
import pytz
from app01.models import *
time_obj = TimeTable.objects.filter(id=1).first()
print(time_obj.time.tzinfo) # UTC -> offset-aware: 包含时区
now = datetime.datetime.now().replace(tzinfo=pytz.timezone('UTC'))
print(now.tzinfo) # UTC -> offset-aware: 包含时区
difference_time = now - time_obj.time # 10:55:30.414490
result = now > time_obj.time # True
将时间戳装换为日期对象
1. 将时间戳转换为日期对象
import datetime
import time
datetime.datetime.fromtimestamp(time.time()) # 2019-05-02 13:51:45.994251 -> 类型: <class 'datetime.datetime'>
datetime.date.fromtimestamp(time.time()) # 2019-05-02 -> 类型: <class 'datetime.datetime'>
# 对时间戳转换为日期对象后进行格式化
datetime.datetime.fromtimestamp(time.time()).strftime('%Y/%m/%d %H:%M:%S') # 2019/05/02 13:51:45 -> 类型: <class 'str'>
datetime.date.fromtimestamp(time.time()).strftime('%Y/%m/%d') # 2019/05/02 -> 类型: <class 'str'>
格式化日期对象
1. 格式化日期对象
- 通俗理解: 将日期对象装换为指定格式的日期字符串
import datetime
datetime.datetime.now().strftime('%Y/%m/%d %H:%M:%S') # 2019/05/02 13:59:38 -> 类型: <class 'str'>
datetime.datetime.now().strftime('%H:%M:%S') # 14:00:51 -> 类型: <class 'str'>
datetime.datetime(year=2019, month=3, day=20, hour=10, minute=1, second=32, microsecond=1).strftime('%Y/%m/%d %H:%M:%S') # 2019/03/20 10:01:32 -> 类型: <class 'str'>
datetime.date(year=2019, month=3, day=20).strftime('%Y/%m/%d') # 2019/03/20 -> 类型: <class 'str'>
将字符串转换成日期对象
1. 将字符串转换成日期对象
import datetime
datetime.datetime.strptime('2017-8-1 18:20:20', '%Y-%m-%d %H:%M:%S') # 2017-08-01 18:20:20 -> 类型: <class 'datetime.datetime'>
datetime.datetime.strptime('2017-8-1', '%Y-%m-%d') # 2017-08-01 00:00:00 -> 类型: <class 'datetime.datetime'>